<template>
  <a-modal
    v-model:open="open"
    title="问卷"
    :footer="null"
    :maskClosable="false"
    :width="1200"
    :bodyStyle="{ height: '600px', overflow: 'hidden auto', padding: '0px 24px 20px' }"
  >
    <div ref="followRef" style="height: 100%; overflow: hidden auto">
      <template v-if="formData">
        <tform :formData="formData" :disabled="true" />
      </template>
      <template v-else>
        <div style="display: flex; align-items: center; justify-content: center; height: 100%">
          <a-empty />
        </div>
      </template>
    </div>
  </a-modal>
</template>
<script setup lang="ts">
import { questionAnswer } from '@/api/healthManaWorkbench'
import tform from '@/components/TForm/index.vue'
import { ref, watch, onMounted } from 'vue'
import { typeOf } from '@/utils/tools'
import dayjs from 'dayjs'

const open = ref(false)
const formData = ref()

const followRef = ref()

watch(open, (val) => {
  if (val) {
    setTimeout(() => {
      if (followRef.value) {
        followRef.value.scrollTop = 0
      }
    }, 0)
  }
})

const init = (params) => {
  open.value = true

  questionAnswer(params)
    .then((res) => {
      const details = res.data.questionnaireInfoVO
      const answers = res.data.patientQuestionnaireAnswerVO

      const data = convert(JSON.parse(details.content))

      data.map((v) => {
        v.list.map((u) => {
          const item = answers.filter((w) => {
            return w.questionId === u.id
          })

          if (u.type.includes('多选')) {
            const checkData: any = []
            item.forEach((w) => {
              checkData.push(w.content)
            })

            u.value = checkData
            u.sort = u.options
              .filter((vo) => {
                return checkData.join(',').includes(vo.value)
              })
              .map((op) => {
                return op.sort
              })
              .join(',')
            u.inputText = u.value
          } else {
            if (item && item.length) {
              u.value = item[0].content
              const findOption = u.options.find((vo) => vo.value == item[0].content)
              u.sort = findOption ? findOption.sort : ''
              u.inputText = item[0].content

              if (u.type === '日期选择') {
                u.value = item[0].content ? dayjs(item[0].content, 'YYYY-MM-DD') : ''
              }
            }
          }
        })
      })

      formData.value = showCondition(data)
    })
    .catch(() => {})
}

const convert = (content) => {
  return content.map((v) => {
    v.list = v.list.map((w) => {
      return {
        id: w.id,
        name: w.questionName,
        type: w.questionType,
        rules: w.rules,
        options: w.options,
        value: w.value,
        showCondition: w.showCondition || null,
        config: w.config || null,
        exc: w.exc ? JSON.parse(w.exc) : {}
      }
    })
    return v
  })
}

const showCondition = (arr) => {
  const obj = {}
  arr.map((v) => {
    v.list.map((u) => {
      obj[u.id] = u
    })
  })

  const List = []

  for (const v of arr) {
    const L = v.list.filter((u) => {
      if (!u.showCondition) {
        return true
      }
      let show = true
      if (Object.prototype.hasOwnProperty.call(u.showCondition, 'show')) {
        show = u.showCondition.show
      }
      let r
      try {
        r = loop(u.showCondition, obj)
      } catch (e) {
        throw new Error(`自定义条件执行异常，异常问题：${u.name}`)
      }
      if (show) {
        return r
      } else {
        return !r
      }
    })

    if (L.length) {
      List.push({
        ...v,
        list: L
      })
    }
  }
  return List
}

const loop = (obj, d) => {
  if (obj.operator === 'AND') {
    return obj.conditions.every((v) => {
      if (v.operator !== 'AND' && v.operator !== 'OR') {
        if (v.operator === '填写完成') {
          return d[v.id].value.trim() !== ''
        } else {
          if (v.id === 'custom') {
            return transformCustom(v.value, d)
          } else if (d[v.id].type.includes('单选')) {
            return d[v.id].sort == v.value
          } else if (d[v.id].type.includes('多选')) {
            return d[v.id].sort.includes(v.value)
          } else if (d[v.id].type === '数字选择') {
            const f = transform(v)
            return f(d[v.id].value)
          } else if (d[v.id].type === '输入') {
            const f = transform(v)
            return f(d[v.id].value)
          }
          if (typeOf(d[v.id].value) === 'string') {
            return d[v.id].value.trim() !== ''
          } else if (typeOf(d[v.id].value) === 'array') {
            return d[v.id].value.length > 0
          } else {
            return true
          }
          // return f(d[v.id].value)
        }
      } else {
        return loop(v, d)
      }
    })
  } else if (obj.operator === 'OR') {
    return obj.conditions.some((v) => {
      if (v.operator !== 'AND' && v.operator !== 'OR') {
        if (v.operator === '填写完成') {
          return d[v.id].value.trim() !== ''
        } else {
          if (v.id === 'custom') {
            return transformCustom(v.value, d)
          } else if (d[v.id].type.includes('单选')) {
            return d[v.id].sort == v.value
          } else if (d[v.id].type.includes('多选')) {
            return d[v.id].sort.includes(v.value)
          } else if (d[v.id].type === '数字选择') {
            const f = transform(v)
            return f(d[v.id].value)
          } else if (d[v.id].type === '输入') {
            const f = transform(v)
            return f(d[v.id].value)
          }
          if (typeOf(d[v.id].value) === 'string') {
            return d[v.id].value.trim() !== ''
          } else if (typeOf(d[v.id].value) === 'array') {
            return d[v.id].value.length > 0
          } else {
            return true
          }
          // return f(d[v.id].value)
        }
      } else {
        return loop(v, d)
      }
    })
  }
  return true
}

const transform = (obj) => {
  if (typeOf(obj.value) === 'string') {
    return new Function('x', 'return x ' + obj.operator + ' "' + obj.value + '"')
  } else {
    return new Function('x', 'return x ' + obj.operator + ' ' + obj.value)
  }
}

const transformCustom = (str, obj) => {
  const s = str.replace(/\$\{(.*?)\}/g, (_, key) => {
    if (Object.prototype.hasOwnProperty.call(obj, key)) {
      return obj[key].value
    } else {
      throw new Error('自定义条件执行异常找不到变量')
    }
  })
  const f = new Function('x', 'return ' + s)
  console.log(f())
  return f()
}

defineExpose({
  init
})
</script>
<style lang="less" scoped></style>
